/*
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html 
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License. 
 * The Original Code is Openbravo ERP. 
 * The Initial Developer of the Original Code is Openbravo SLU 
 * All portions are Copyright (C) 2001-2011 Openbravo SLU 
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
package org.openbravo.furniture.ad_actionButton;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.openbravo.advpaymentmngt.dao.AdvPaymentMngtDao;
import org.openbravo.advpaymentmngt.utility.FIN_Utility;
import org.openbravo.base.exception.OBException;
import org.openbravo.base.filter.IsIDFilter;
import org.openbravo.base.provider.OBProvider;
import org.openbravo.base.secureApp.HttpSecureAppServlet;
import org.openbravo.base.secureApp.VariablesSecureApp;
import org.openbravo.base.session.OBPropertiesProvider;
import org.openbravo.dal.core.DalUtil;
import org.openbravo.dal.service.OBDal;
import org.openbravo.dal.service.OBQuery;
import org.openbravo.erpCommon.ad_actionButton.ActionButtonDefaultData;
import org.openbravo.erpCommon.businessUtility.BpartnerMiscData;
import org.openbravo.erpCommon.businessUtility.Tax;
import org.openbravo.erpCommon.businessUtility.WindowTabs;
import org.openbravo.erpCommon.reference.PInstanceProcessData;
import org.openbravo.erpCommon.utility.ComboTableData;
import org.openbravo.erpCommon.utility.DateTimeData;
import org.openbravo.erpCommon.utility.LeftTabsBar;
import org.openbravo.erpCommon.utility.NavigationBar;
import org.openbravo.erpCommon.utility.OBError;
import org.openbravo.erpCommon.utility.OBErrorBuilder;
import org.openbravo.erpCommon.utility.OBMessageUtils;
import org.openbravo.erpCommon.utility.SequenceIdData;
import org.openbravo.erpCommon.utility.ToolBar;
import org.openbravo.erpCommon.utility.Utility;
import org.openbravo.model.common.enterprise.DocumentType;
import org.openbravo.model.common.order.Order;
import org.openbravo.model.common.order.OrderDiscount;
import org.openbravo.model.common.order.OrderLine;
import org.openbravo.model.common.order.OrderLineOffer;
import org.openbravo.model.financialmgmt.payment.FIN_PaymentSchedule;
import org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail;
import org.openbravo.model.financialmgmt.tax.TaxRate;
import org.openbravo.model.pricing.pricelist.PriceListVersion;
import org.openbravo.model.project.Project;
import org.openbravo.service.db.CallStoredProcedure;
import org.openbravo.service.db.DalConnectionProvider;
import org.openbravo.utils.Replace;
import org.openbravo.xmlEngine.XmlDocument;

public class CreateOrderFromProposal extends HttpSecureAppServlet {
  private static final long serialVersionUID = 1L;
  private AdvPaymentMngtDao dao;

  private static final BigDecimal ZERO = new BigDecimal(0.0);

  // String neworderid = "";

  public void init(ServletConfig config) {
    super.init(config);
    boolHist = false;
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,
      ServletException {
    VariablesSecureApp vars = new VariablesSecureApp(request);

    if (vars.commandIn("DEFAULT")) {
      String strProcessId = vars.getStringParameter("inpProcessId");
      String strWindow = vars.getStringParameter("inpwindowId");
      String strTab = vars.getStringParameter("inpTabId");
      String strKey = vars.getGlobalVariable("inpcOrderId", strWindow + "|C_Order_ID");
      log4j.debug("Create order from proposal - default - strProcessId: " + strProcessId);
      log4j.debug("Create order from proposal - default - strWindow: " + strWindow);
      log4j.debug("Create order from proposal - default - strTab: " + strTab);
      log4j.debug("Create order from proposal - default - strKey: " + strKey);
      printPage(response, vars, strKey, strWindow, strTab, strProcessId);
    } else if (vars.commandIn("SAVE")) {
      String strKey = vars.getStringParameter("inpcOrderId");
      String strWindow = vars.getStringParameter("inpwindowId");
      String strTab = vars.getStringParameter("inpTabId");
      String strWindowPath = Utility.getTabURL(strTab, "R", true);
      if (strWindowPath.equals(""))
        strWindowPath = strDefaultServlet;

      OBError myError = processButton(vars, strKey, strWindow, false);
      String strProcessId = vars.getStringParameter("inpProcessId");
      vars.setMessage(strTab, myError);
      // printPageClosePopUp(response, vars, strWindowPath);
      printPage(response, vars, strKey, strWindow, strTab, strProcessId);
    } else if (vars.commandIn("SAVE_ORDER")) {
      String strKey = vars.getStringParameter("inpcOrderId");
      String strWindow = vars.getStringParameter("inpwindowId");
      String strTab = vars.getStringParameter("inpTabId");
      String strWindowPath = Utility.getTabURL(strTab, "R", true);
      if (strWindowPath.equals(""))
        strWindowPath = strDefaultServlet;

      // OBError myError = processButton(vars, strKey, strWindow, true);
      OBError myError = processButtonCreate(vars, strKey, strWindow, true);
      log4j.debug("myerror type: " + myError.getType());

      if (myError.getType().equals("Success")) {
        myError = createpayment(response, request, vars, strKey, strWindow);
      }

      String strProcessId = vars.getStringParameter("inpProcessId");
      vars.setMessage(strTab, myError);
      printPageClosePopUp(response, vars, strWindowPath);
      // printPage(response, vars, strKey, strWindow, strTab, strProcessId);
    } else if (vars.commandIn("REMOVE")) {
      String strRemoveOrder = vars.getStringParameter("inpOrderRemoveId", "");
      String strRemoveMovement = vars.getStringParameter("inpMovementRemoveId", "");
      String strKey = vars.getStringParameter("inpcOrderId");
      String strWindow = vars.getStringParameter("inpwindowId");
      String strTab = vars.getStringParameter("inpTabId");
      String strWindowPath = Utility.getTabURL(strTab, "R", true);
      if (strWindowPath.equals(""))
        strWindowPath = strDefaultServlet;

      String strProcessId = vars.getStringParameter("inpProcessId");
      // printPageClosePopUp(response, vars, strWindowPath);
      printPage(response, vars, strKey, strWindow, strTab, strProcessId);
    } else if (vars.commandIn("SAVE_COMPLETE")) {
      String strKey = vars.getStringParameter("inpcOrderId");
      String strWindow = vars.getStringParameter("inpwindowId");
      String strTab = vars.getStringParameter("inpTabId");
      String strWindowPath = Utility.getTabURL(strTab, "R", true);
      log4j.debug("Create order from proposal - complete - key: " + strKey);
      log4j.debug("Create order from proposal - complete - window: " + strWindow);
      log4j.debug("Create order from proposal - complete - tab: " + strTab);
      log4j.debug("Create order from proposal - complete - window path: " + strWindowPath);
      if (strWindowPath.equals(""))
        strWindowPath = strDefaultServlet;
      OBError myError = processComplete(vars, strKey, strWindow);
      vars.setMessage(strTab, myError);
      printPageClosePopUp(response, vars, strWindowPath);
    } else
      pageErrorPopUp(response);
  }

  private OBError processComplete(VariablesSecureApp vars, String strKey, String windowId) {
    OBError myMessage = new OBError();
    StringBuffer txtOrder = new StringBuffer();
    Connection conn = null;
    try {
      // The process has to complete all the orders generated at this point. To do that, we need to
      // obtain the proposal/order id, and obtaining all the data related
      // complete all the orders and movements
      conn = getTransactionConnection();
      // Complete warehouse movements
      String pinstance = "";
      CreateOrderFromProposalData[] dataMovements = CreateOrderFromProposalData.selectMovements(
          this, strKey);
      log4j.debug("Create order from proposal - complete process - dataMovements.length: "
          + dataMovements.length);
      for (int i = 0; i < dataMovements.length; i++) {
        if (!"".equals(dataMovements[i].mMovementId)) {
          pinstance = SequenceIdData.getUUID();
          try {
            PInstanceProcessData.insertPInstance(this, pinstance, "122",
                dataMovements[i].mMovementId, "N", vars.getUser(), vars.getClient(), vars.getOrg());
          } catch (ServletException ex) {
            myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
            releaseRollbackConnection(conn);
            return myMessage;
          }
          CreateOrderFromProposalData.mMovementPost(conn, this, pinstance);
          PInstanceProcessData[] pinstanceData = PInstanceProcessData.selectConnection(conn, this,
              pinstance);
          myMessage = Utility.getProcessInstanceMessage(this, vars, pinstanceData);
          if (myMessage.getType().equals("Error")) {
            releaseRollbackConnection(conn);
            return myMessage;
          }
        }
      }
      // Complete purchase orders

      CreateOrderFromProposalData[] dataPurchase = CreateOrderFromProposalData.selectPurchase(this,
          strKey);
      log4j.debug("Create order from proposal - complete process - dataPurchase.length: "
          + dataPurchase.length);
      for (int i = 0; i < dataPurchase.length; i++) {
        if (!"".equals(dataPurchase[i].cOrderId)) {
          pinstance = SequenceIdData.getUUID();
          try {
            PInstanceProcessData.insertPInstance(this, pinstance, "104", dataPurchase[i].cOrderId,
                "N", vars.getUser(), vars.getClient(), vars.getOrg());
          } catch (ServletException ex) {
            myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
            releaseRollbackConnection(conn);
            return myMessage;
          }
          CreateOrderFromProposalData.cOrderPost(conn, this, pinstance);
          PInstanceProcessData[] pinstanceData = PInstanceProcessData.selectConnection(conn, this,
              pinstance);
          myMessage = Utility.getProcessInstanceMessage(this, vars, pinstanceData);
          if (myMessage.getType().equals("Error")) {
            releaseRollbackConnection(conn);
            return myMessage;
          }
        }
      }

      // Complete sales order created related to the proposal, if exits

      CreateOrderFromProposalData[] dataSales = CreateOrderFromProposalData.selectSales(this,
          strKey);
      log4j.debug("Create order from proposal - complete process - dataSales.length: "
          + dataSales.length);
      if (dataSales != null && dataSales.length > 0) {
        if (!"".equals(dataSales[0].cOrderId)) {
          pinstance = SequenceIdData.getUUID();
          try {
            PInstanceProcessData.insertPInstance(this, pinstance, "104", dataSales[0].cOrderId,
                "N", vars.getUser(), vars.getClient(), vars.getOrg());
          } catch (ServletException ex) {
            myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
            releaseRollbackConnection(conn);
            return myMessage;
          }
          CreateOrderFromProposalData.cOrderPost(conn, this, pinstance);
          PInstanceProcessData[] pinstanceData = PInstanceProcessData.selectConnection(conn, this,
              pinstance);
          myMessage = Utility.getProcessInstanceMessage(this, vars, pinstanceData);
          if (myMessage.getType().equals("Error")) {
            releaseRollbackConnection(conn);
            return myMessage;
          }
        }
      }
      // Complete proposal/order of reference
      //
      // CreateOrderFromProposalData[] dataSalesReference =
      // CreateOrderFromProposalData.selectSales(this, strKey);
      log4j.debug("Create order from proposal - complete process - complete order: " + strKey);
      pinstance = SequenceIdData.getUUID();
      try {
        PInstanceProcessData.insertPInstance(this, pinstance, "104", strKey, "N", vars.getUser(),
            vars.getClient(), vars.getOrg());
      } catch (ServletException ex) {
        myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
        releaseRollbackConnection(conn);
        return myMessage;
      }
      CreateOrderFromProposalData.cOrderPost(conn, this, pinstance);
      PInstanceProcessData[] pinstanceData = PInstanceProcessData.selectConnection(conn, this,
          pinstance);
      myMessage = Utility.getProcessInstanceMessage(this, vars, pinstanceData);
      if (myMessage.getType().equals("Error")) {
        releaseRollbackConnection(conn);
        return myMessage;
      }
      releaseCommitConnection(conn);
    } catch (Exception e) {
      try {
        releaseRollbackConnection(conn);
      } catch (Exception ignored) {
      }
      log4j.warn("Rollback in transaction", e);
      // myMessage = new OBError();
      myMessage.setType("Error");
      myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
      myMessage.setMessage(Utility.messageBD(this, "ProcessRunError", vars.getLanguage()));
      return myMessage;
    }
    myMessage = new OBError();
    myMessage.setType("Success");
    myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
    // myMessage.setMessage(Utility.messageBD(this, "RecordsCopied", vars.getLanguage()) + " " + i);
    return myMessage;
  }

  private OBError processButtonCreate(VariablesSecureApp vars, String strKey, String windowId,
      boolean createorder) {
    int i = 0;
    OBError myMessage = null;
    StringBuffer txtOrder = new StringBuffer();
    Connection conn = null;
    boolean recalculatePrices = false;
    Order objCloneOrder = new Order();
    try {
      // Create Sales Order
      String orderId = strKey;
      Order objOrder = OBDal.getInstance().get(Order.class, orderId);
      objCloneOrder = (Order) DalUtil.copy(objOrder, false);

      if (FIN_Utility.isBlockedBusinessPartner(objOrder.getBusinessPartner().getId(), true, 1)) {
        // If the Business Partner is blocked, the Order should not be completed.
        OBError msg = new OBError();
        msg.setType("Error");
        msg.setMessage(OBMessageUtils.messageBD("ThebusinessPartner") + " "
            + objOrder.getBusinessPartner().getIdentifier() + " "
            + OBMessageUtils.messageBD("BusinessPartnerBlocked"));
        OBDal.getInstance().rollbackAndClose();
        return myMessage;
      }

      // Set status of the new Order to Draft and Processed = N
      objCloneOrder.setDocumentAction("CO");
      objCloneOrder.setDocumentStatus("DR");
      objCloneOrder.setProcessed(false);
      objCloneOrder.setPosted("N");

      // Set the Sales Order Document Type
      DocumentType docType = objCloneOrder.getDocumentType().getDocumentTypeForOrder();
      if (docType == null) {
        OBDal.getInstance().rollbackAndClose();
        OBError result = OBErrorBuilder.buildMessage(null, "error", "@NoOrderDocType@");
        // bundle.setResult(result);
        return result;
      }

      // Set values of the Sales Order Header
      objCloneOrder.setDocumentType(docType);
      objCloneOrder.setTransactionDocument(docType);
      objCloneOrder.setProcessed(false);
      objCloneOrder.setSalesTransaction(true);
      objCloneOrder.setDocumentNo(null);
      objCloneOrder.setOrderDate(new Date());
      objCloneOrder.setRejectReason(null);
      objCloneOrder.setValidUntil(null);
      objCloneOrder.setSummedLineAmount(BigDecimal.ZERO);
      objCloneOrder.setGrandTotalAmount(BigDecimal.ZERO);
      OBDal.getInstance().save(objCloneOrder);
      OBDal.getInstance().flush();
      OBDal.getInstance().refresh(objCloneOrder);

      Map<String, BigDecimal> taxForDiscounts = new HashMap<String, BigDecimal>();
      int lineNo = 10;

      // Copy the Lines of the Quotation in the new Sales Order.
      for (OrderLine ordLine : objOrder.getOrderLineList()) {
        if (ordLine.getOrderDiscount() != null) {
          // If the line is a discount line do not copy it
          continue;
        }

        // Copy line to the new Sales Order
        OrderLine objCloneOrdLine = (OrderLine) DalUtil.copy(ordLine, false);
        Project project = objOrder.getProject();
        String strProjectID = project == null ? "" : project.getId();
        // Recalculate Taxes
        String dateFormatString = OBPropertiesProvider.getInstance().getOpenbravoProperties()
            .getProperty("dateFormat.java");
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatString);
        String strCTaxID = Tax.get(new DalConnectionProvider(false), ordLine.getProduct().getId(),
            dateFormat.format(new Date()), ordLine.getOrganization().getId(), ordLine
                .getWarehouse().getId(), ordLine.getSalesOrder().getInvoiceAddress().getId(),
            ordLine.getSalesOrder().getPartnerAddress().getId(), strProjectID, true);
        TaxRate lineTax = OBDal.getInstance().get(TaxRate.class, strCTaxID);
        objCloneOrdLine.setTax(lineTax);

        // Update the HashMap of the Taxes. HashMap<TaxId, TotalAmount>
        BigDecimal price = BigDecimal.ZERO;
        if (objCloneOrder.getPriceList().isPriceIncludesTax()) {
          price = objCloneOrdLine.getGrossUnitPrice();
        } else {
          price = objCloneOrdLine.getUnitPrice();
        }
        if (taxForDiscounts.containsKey(strCTaxID)) {
          taxForDiscounts.put(strCTaxID, taxForDiscounts.get(strCTaxID).add(price));
        } else {
          taxForDiscounts.put(strCTaxID, price);
        }

        if (recalculatePrices) {
          recalculatePrices(objOrder, ordLine, objCloneOrder, objCloneOrdLine, lineTax);
        } else {
          for (OrderLineOffer offer : ordLine.getOrderLineOfferList()) {
            // Copy Promotions and Discounts.
            OrderLineOffer objCloneOffer = (OrderLineOffer) DalUtil.copy(offer, false);
            objCloneOffer.setSalesOrderLine(objCloneOrdLine);
            objCloneOrdLine.getOrderLineOfferList().add(objCloneOffer);
          }
        }
        // Set last values of new Sales Order line
        objCloneOrdLine.setSalesOrder(objCloneOrder);
        objCloneOrdLine.setReservedQuantity(BigDecimal.ZERO);
        objCloneOrdLine.setDeliveredQuantity(BigDecimal.ZERO);
        objCloneOrdLine.setInvoicedQuantity(BigDecimal.ZERO);
        objCloneOrdLine.setQuotationLine(ordLine);
        objCloneOrder.getOrderLineList().add(objCloneOrdLine);
        lineNo = lineNo + 10;
      }

      OBDal.getInstance().flush();
      OBDal.getInstance().refresh(objCloneOrder);

      // Delete created discounts for Order
      for (OrderDiscount disCloneLine : objCloneOrder.getOrderDiscountList()) {
        OBDal.getInstance().remove(disCloneLine);
      }
      objCloneOrder.getOrderDiscountList().clear();

      OBDal.getInstance().flush();
      OBDal.getInstance().refresh(objCloneOrder);

      BigDecimal cumulativeDiscount = new BigDecimal(100);

      // Create the discounts to be able to add the appropriate discount_id in c_orderline
      for (OrderDiscount disLine : objOrder.getOrderDiscountList()) {
        // Copy discounts
        OrderDiscount objCloneDiscount = (OrderDiscount) DalUtil.copy(disLine, false);
        objCloneDiscount.setSalesOrder(objCloneOrder);
        objCloneOrder.getOrderDiscountList().add(objCloneDiscount);
        if (!recalculatePrices) {
          // Copy the Invoice Lines that are created from the Discounts
          Iterator it = taxForDiscounts.entrySet().iterator();
          OBDal.getInstance().flush();
          while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            BigDecimal discountAmount = BigDecimal.ZERO;

            if (objCloneDiscount.isCascade()) {
              discountAmount = objCloneDiscount.getDiscount().getDiscount();
              discountAmount = cumulativeDiscount.multiply(discountAmount).divide(
                  new BigDecimal(100));

            } else {
              discountAmount = objCloneDiscount.getDiscount().getDiscount();
            }
            cumulativeDiscount = cumulativeDiscount.subtract(discountAmount);

            OrderLine olDiscount = generateOrderLineDiscount(e, objCloneDiscount, objOrder,
                objCloneOrder, lineNo, cumulativeDiscount, discountAmount);
            lineNo = lineNo + 10;
            objCloneOrder.getOrderLineList().add(olDiscount);
          }
        }
      }

      OBDal.getInstance().flush();
      OBDal.getInstance().refresh(objCloneOrder);

      if (recalculatePrices) {
        // If prices are going to be recalculated, call C_Order_Post
        callCOrderPost(objCloneOrder);
        OBDal.getInstance().flush();
        OBDal.getInstance().refresh(objCloneOrder);
      } else {
        // Create the Payment Plan for the new Sales Order
        FIN_PaymentSchedule ps = generatePaymentPlan(objCloneOrder);
        FIN_PaymentScheduleDetail psd = generatePaymentPlanDetails(objCloneOrder, ps);
        ps.getFINPaymentScheduleDetailOrderPaymentScheduleList().add(psd);
        objCloneOrder.getFINPaymentScheduleList().add(ps);
        OBDal.getInstance().save(ps);

        OBDal.getInstance().save(psd);
      }

      // Change Sales Order Status to Completed
      objCloneOrder.setDocumentAction("RE");
      objCloneOrder.setDocumentStatus("CO");
      objCloneOrder.setProcessed(true);
      objCloneOrder.setQuotation(objOrder);

      // Set the Status of the Quotation to Closed - Converted
      objOrder.setDocumentStatus("CA");

      OBDal.getInstance().save(objOrder);
      OBDal.getInstance().save(objCloneOrder);

      OBDal.getInstance().flush();
      OBDal.getInstance().refresh(objCloneOrder);
      OBDal.getInstance().refresh(objOrder);

      OBDal.getInstance().commitAndClose();
      OBError result = OBErrorBuilder.buildMessage(null, "success", "@SalesOrderDocumentno@ "
          + objCloneOrder.getDocumentNo() + " @beenCreated@");
      // bundle.setResult(result);

    } catch (Exception e) {
      try {
        releaseRollbackConnection(conn);
      } catch (Exception ignored) {
      }
      log4j.warn("Rollback in transaction", e);
      myMessage = new OBError();
      myMessage.setType("Error");
      myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
      myMessage.setMessage(Utility.messageBD(this, "ProcessRunError", vars.getLanguage()));
      return myMessage;
    }
    myMessage = new OBError();
    myMessage.setType("Success");
    myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
    myMessage.setMessage("Creado el pedido " + objCloneOrder.getDocumentNo());

    // myMessage.setMessage(Utility.messageBD(this, "RecordsCopied", vars.getLanguage()) + " " + i);
    return myMessage;
  }

  private OBError createpayment(HttpServletResponse response, HttpServletRequest request,
      VariablesSecureApp vars, String strKey, String windowId) {
    OBError myMessage = null;
    boolean isReceipt = true;
    String strAction = null;
    strAction = (isReceipt ? "PRP" : "PPP");
    Connection conn = null;

    try {
      conn = getTransactionConnection();
      CreateOrderFromProposalData[] lastorder = CreateOrderFromProposalData.selectlastorder2(this,
          "1");
      strAction = (isReceipt ? "PRP" : "PPP");

      log4j.debug("neworderid: llegando");
      log4j.debug("neworderid: " + lastorder[0].cOrderId);

      String paymentInId = SequenceIdData.getUUID();
      log4j.debug("neworderid: " + lastorder[0].cOrderId);
      // Order objOrder = OBDal.getInstance().get(Order.class, neworderid);
      // String paymentdocno = Utility.getDocumentNo(this, vars.getClient(), "FIN_Payment", true);

      // String financialAccountId = CreateOrderFromProposal.selectfinancialaccount(this,
      // vars.getClient());
      String financialAccountId = "92B41D178D204EB78C03262C6D28CD6D";
      String doctype = "D132517AE775435B8EB2832CC61FCAB1";
      String paymentdocno = Utility.getDocumentNo(conn, this, vars,
          "E547CE89D4C04429B6340FFA44E70716", "FIN_Payment", "", doctype, false, true);
      log4j.debug("paymentdocno: " + paymentdocno);
      CreateOrderFromProposalData.insertpayment(conn, this, paymentInId, lastorder[0].adClientId,
          lastorder[0].adOrgId, vars.getUser(), lastorder[0].cBpartnerId,
          lastorder[0].paymentmethod, paymentdocno, financialAccountId, doctype);

      releaseCommitConnection(conn);
    } catch (Exception e) {
      try {
        releaseRollbackConnection(conn);
      } catch (Exception ignored) {
      }
      log4j.warn("Rollback in transaction", e);
      myMessage = new OBError();
      myMessage.setType("Error");
      myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
      myMessage.setMessage(Utility.messageBD(this, "ProcessRunError", vars.getLanguage()));
      return myMessage;
    }

    myMessage = new OBError();
    myMessage.setType("Success");
    myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
    myMessage.setMessage("");

    // myMessage.setMessage(Utility.messageBD(this, "RecordsCopied", vars.getLanguage()) + " " + i);
    return myMessage;
    /*
     * log4j.debug("neworderid: llegando"); log4j.debug("neworderid: " + neworderid); try { conn =
     * getTransactionConnection(); String paymentInId = SequenceIdData.getUUID();
     * log4j.debug("neworderid: " + neworderid); Order objOrder =
     * OBDal.getInstance().get(Order.class, neworderid); String paymentdocno =
     * Utility.getDocumentNo(this, vars.getClient(), "FIN_Paymnet", true); // String
     * financialAccountId = CreateOrderFromProposal.selectfinancialaccount(this, //
     * vars.getClient()); String financialAccountId = "92B41D178D204EB78C03262C6D28CD6D"; String
     * doctype = "D132517AE775435B8EB2832CC61FCAB1"; CreateOrderFromProposalData.insertpayment(conn,
     * this, paymentInId, objOrder.getClient() .getId(), objOrder.getOrganization().getId(),
     * vars.getUser(), objOrder .getBusinessPartner().getId(), objOrder.getPaymentMethod().getId(),
     * paymentdocno, financialAccountId, doctype);
     * 
     * } catch (Exception e) { log4j.warn("Rollback in transaction", e); myMessage = new OBError();
     * myMessage.setType("Error"); myMessage.setTitle(Utility.messageBD(this, "Error",
     * vars.getLanguage())); myMessage.setMessage(Utility.messageBD(this, "ProcessRunError",
     * vars.getLanguage())); return myMessage; } myMessage = new OBError();
     * myMessage.setType("Success"); myMessage.setTitle(Utility.messageBD(this, "Success",
     * vars.getLanguage()));
     * 
     * // myMessage.setMessage(Utility.messageBD(this, "RecordsCopied", vars.getLanguage()) + " " +
     * i);
     */

  }

  private void businessPartnerBlocked(HttpServletResponse response, VariablesSecureApp vars,
      String strBPartnerName) throws IOException, ServletException {

    try {
      JSONObject json = new JSONObject();
      json.put("text", "SelectedBPartnerBlocked");
      response.setContentType("text/html; charset=UTF-8");
      PrintWriter out = response.getWriter();
      out.println("objson = " + json);
      out.close();
    } catch (JSONException e) {
      log4j.error("AddOrderOrInvoice - Callback", e);
    }
  }

  private OBError processButton(VariablesSecureApp vars, String strKey, String windowId,
      boolean createorder) {
    int i = 0;
    OBError myMessage = null;
    StringBuffer txtOrder = new StringBuffer();
    Connection conn = null;
    try {
      conn = getTransactionConnection();

      // Create Business partner if the partner does not exist, or update it, if the partner exist

      /*
       * String strcBpartnerId = vars.getStringParameter("inpcBpartnerId", ""); String
       * strpartnerName = vars.getStringParameter("inppartnerName", ""); String strlocationName =
       * vars.getStringParameter("inplocationName", ""); String strPostal =
       * vars.getStringParameter("inpPostal", ""); String strcityName =
       * vars.getStringParameter("inpcityName", ""); String strPhone =
       * vars.getStringParameter("inpphone", ""); String strcRegionId =
       * vars.getStringParameter("inpcRegionId", ""); String strfinPaymentmethodId =
       * vars.getStringParameter("inpfinPaymentmethodId", "");
       * 
       * String strcLocationId = vars.getStringParameter("inpcLocationId", ""); String
       * strcBpartnerLocationid = vars.getStringParameter("inpcBpartnerLocationId", "");
       * 
       * log4j.debug("Create order from proposal - Create business partner - strcBpartnerId: " +
       * strcBpartnerId);
       * log4j.debug("Create order from proposal - Create business partner - partnerName: " +
       * strpartnerName);
       * log4j.debug("Create order from proposal - Create business partner - location name: " +
       * strlocationName);
       * log4j.debug("Create order from proposal - Create business partner - postal: " + strPostal);
       * log4j.debug("Create order from proposal - Create business partner - city name: " +
       * strcityName); log4j.debug("Create order from proposal - Create business partner - phone: "
       * + strPhone);
       * log4j.debug("Create order from proposal - Create business partner - region id: " +
       * strcRegionId);
       * log4j.debug("Create order from proposal - Create business partner - payment method id: " +
       * strfinPaymentmethodId);
       * log4j.debug("Create order from proposal - Create business partner - location id: " +
       * strcLocationId);
       * log4j.debug("Create order from proposal - Create business partner - partner location id: "
       * + strcBpartnerLocationid);
       */
      if (!createorder) {
        /*
         * if ("".equals(strcBpartnerId)) { // The partner does not exists, so the system must
         * create it
         * log4j.debug("Create order from proposal - Create business partner - create a new partner"
         * ); strcBpartnerId = SequenceIdData.getUUID();
         * 
         * String strcBpGroupId = CreateOrderFromProposalData.selectGroup(this);
         * 
         * log4j.debug("Create order from proposal - Create business partner - default group id: " +
         * strcBpGroupId);
         * 
         * // partnerid, client, org, user, value, name, groupid, mpricelistid, finpaymentmethodid
         * String strmPriceListId = CreateOrderFromProposalData.defaultPriceList(this, "Y",
         * vars.getClient());
         * log4j.debug("Create order from proposal - Create business partner - default pricelist id: "
         * + strmPriceListId); String value = strpartnerName; if (value.length() > 40) value =
         * strpartnerName.substring(0, 40); CreateOrderFromProposalData.insert(conn, this,
         * strcBpartnerId, vars.getClient(), "0", vars.getUser(), value, strpartnerName,
         * strcBpGroupId, strmPriceListId, strfinPaymentmethodId);
         * 
         * log4j.debug("Create order from proposal - Create business partner - partner inserted");
         * 
         * strcLocationId = SequenceIdData.getUUID(); // locationid, client, org, user, address1,
         * address2, postal, city, country, region CreateOrderFromProposalData.insertLocation( conn,
         * this, strcLocationId, vars.getClient(), "0", vars.getUser(), (strlocationName.length() >
         * 60) ? strlocationName.substring(0, 60) : strlocationName, (strlocationName.length() > 60)
         * ? strlocationName.substring(61, strlocationName.length()) : "", strPostal, strcityName,
         * "106", strcRegionId);
         * 
         * log4j.debug("Create order from proposal - Create business partner - location inserted");
         * 
         * strcBpartnerLocationid = SequenceIdData.getUUID(); // bpartnerlocationid, client, org,
         * user, name, billto, shipto, payfrom, remitto, phone, // partnerid, locationid
         * CreateOrderFromProposalData.insertBpartnerLocation(conn, this, strcBpartnerLocationid,
         * vars.getClient(), "0", vars.getUser(), strlocationName, "Y", "Y", "N", "N", strPhone,
         * strcBpartnerId, strcLocationId);
         * 
         * log4j .debug(
         * "Create order from proposal - Create business partner - business partner location inserted"
         * );
         * 
         * // Assign the correct business partner to the order created // cbpartnerid, billtoid,
         * cbpartnerlocationid, mpricelistid, finpaymentmethodid, corderid
         * 
         * CreateOrderFromProposalData.updateOrder(conn, this, vars.getUser(), strcBpartnerId,
         * strcBpartnerLocationid, strmPriceListId, strfinPaymentmethodId, strKey);
         * 
         * log4j.debug("Create order from proposal - Create business partner - order updated"); }
         * else { // The partner exists, so the system has to update it
         * 
         * log4j
         * .debug("Create order from proposal - Create business partner - partner exists, update it"
         * );
         * 
         * CreateOrderFromProposalData.update(conn, this, vars.getUser(), (strpartnerName.length() >
         * 40) ? strpartnerName.substring(0, 40) : strpartnerName, strpartnerName, strcBpartnerId);
         * 
         * log4j.debug("Create order from proposal - Create business partner - update partner");
         * 
         * CreateOrderFromProposalData.updateLocation( conn, this, vars.getUser(),
         * (strlocationName.length() > 60) ? strlocationName.substring(0, 60) : strlocationName,
         * (strlocationName.length() > 60) ? strlocationName.substring(61, strlocationName.length())
         * : "", strPostal, strcityName, strcRegionId, strcLocationId);
         * 
         * log4j.debug("Create order from proposal - Create business partner - update location");
         * 
         * CreateOrderFromProposalData.updatePartnerLocation(conn, this, vars.getUser(),
         * strlocationName, strPhone, strcBpartnerLocationid);
         * 
         * log4j .debug(
         * "Create order from proposal - Create business partner - update business partner location"
         * );
         * 
         * }
         */

        // Material in warehouse not reserved. Possible actions:
        // 1) Reserve the material: warehouse movement between warehouse and reserved warehouse
        // 2) Order new material: create a new purchase order

        String strreservematerial = vars.getInStringParameter("inpReserveMaterial", "");
        String strordermaterial = vars.getInStringParameter("inpOrderMaterial", "");

        log4j
            .debug("Create order from proposal - Material in warehose not reserved - strreservematerial: "
                + strreservematerial);
        log4j
            .debug("Create order from proposal - Material in warehose not reserved - strordermaterial: "
                + strordermaterial);

        if (!"".equals(strreservematerial)) {
          // StringTokenizer + for - insert material movement lines with one material movement
          // header
          // Material movement
          if (strreservematerial.startsWith("("))
            strreservematerial = strreservematerial.substring(1, strreservematerial.length() - 1);
          if (!strreservematerial.equals("")) {
            strreservematerial = Replace.replace(strreservematerial, "'", "");
            StringTokenizer st = new StringTokenizer(strreservematerial, ",", false);
            // Movementid, client, org, user, name, description, movementdate, documentno
            log4j
                .debug("Create order from proposal - Material in warehose not reserved - Material movement");
            String strmMovementId = SequenceIdData.getUUID();
            String strDocumentno = Utility.getDocumentNo(this, vars, "", "M_Movement", "", "",
                false, true);
            log4j
                .debug("Create order from proposal - Material in warehose not reserved - Material movement - strKey: "
                    + strKey);
            CreateOrderFromProposalData[] dataOrder = CreateOrderFromProposalData.selectOrder(this,
                strKey);
            CreateOrderFromProposalData.insertMovement(conn, this, strmMovementId,
                vars.getClient(), vars.getOrg(), vars.getUser(), dataOrder[0].documentno + " - "
                    + dataOrder[0].dateordered, dataOrder[0].documentno + " - "
                    + dataOrder[0].dateordered, dataOrder[0].dateordered, strDocumentno);
            log4j
                .debug("Create order from proposal - Material in warehose not reserved - Material movement - Movement header inserted");
            int line = 10;
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - identifier: "
                      + identifier);
              String strmProductId = identifier.substring(0, 32);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - product: "
                      + strmProductId);
              String strmLocatorId = (identifier.length() > 32) ? identifier.substring(32, 64) : "";
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - locator: "
                      + strmLocatorId);
              String strmAttributesetinstanceId = (identifier.length() > 64) ? identifier
                  .substring(64, identifier.length()) : "";
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - attribute: "
                      + strmAttributesetinstanceId);
              String strmovementqty = vars.getStringParameter("inpReserveMaterialQty" + identifier,
                  "0");

              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - attribute: "
                      + strmAttributesetinstanceId);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - locator: "
                      + strmLocatorId);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - movement qty: "
                      + strmovementqty);

              // Movementlineid, client, org, user, movement, locator, locatorto, product, line,
              // movementqty, description, attributesetinstance, productuom, quantityorder, uom
              String strmMovementLineId = SequenceIdData.getUUID();
              String strcUomId = CreateOrderFromProposalData.selectUom(this, strmProductId);
              String strmLocatortoId = CreateOrderFromProposalData.selectLocatorto(this);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - uom: "
                      + strcUomId);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - locator to: "
                      + strmLocatortoId);
              CreateOrderFromProposalData.insertMovementLine(conn, this, strmMovementLineId,
                  vars.getClient(), vars.getOrg(), vars.getUser(), strmMovementId, strmLocatorId,
                  strmLocatortoId, strmProductId, new Integer(line).toString(), strmovementqty, "",
                  strmAttributesetinstanceId, "", "", strcUomId);

              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Material movement - movement line inserted");

              line = line + 10;

              // Assign movement line to order line, to keep the lines related
              // First, check if a line exist to this orderline
              CreateOrderFromProposalData.updateMatchMovement(conn, this, strmMovementLineId,
                  strmProductId, strKey);
            }
          }
        }

        if (!"".equals(strordermaterial)) {
          // Create a new purchase order
          // StringTokenizer + for - insert purchase orders lines with one line per header
          if (strordermaterial.startsWith("("))
            strordermaterial = strordermaterial.substring(1, strordermaterial.length() - 1);
          if (!strordermaterial.equals("")) {
            strordermaterial = Replace.replace(strordermaterial, "'", "");
            StringTokenizer st = new StringTokenizer(strordermaterial, ",", false);
            log4j
                .debug("Create order from proposal - Material in warehose not reserved - Create purchase order");
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strmProductId = identifier.substring(0, 32);
              // String strmAttributesetinstanceId = identifier.substring(32, 63);
              // String strmLocatorId = identifier.substring(64, 95);
              String strmovementqty = vars.getStringParameter("inpOrderMaterialQty" + identifier,
                  "0");
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Create purchase order - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Create purchase order - movementqty: "
                      + strmovementqty);

              String strcOrderId = SequenceIdData.getUUID();
              myMessage = insertOrderHeader(conn, vars, strcOrderId, strmProductId, "N", null);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Create purchase order - Header inserted");
              if (myMessage != null) {
                if (myMessage.getType() != "Error") {
                  txtOrder.append(myMessage.getMessage());
                } else {
                  myMessage.setMessage(Utility.messageBD(this, "Created", vars.getLanguage()));
                  releaseRollbackConnection(conn);
                }
              }
              int line = 10;
              myMessage = insertOrderLine(conn, vars, strcOrderId, line, strmProductId,
                  strmovementqty, null, false, strKey);
              log4j
                  .debug("Create order from proposal - Material in warehose not reserved - Create purchase order - Line inserted");
              line = line + 10;
            }
          }
        }

        // Material to order
        // One action, order the material and reserve it, when it arrives.

        strreservematerial = vars.getInStringParameter("inpReserveToOrder", "");
        strordermaterial = vars.getInStringParameter("inpOrderToOrder", "");

        log4j.debug("Create order from proposal - Material to order - strreservematerial: "
            + strreservematerial);
        log4j.debug("Create order from proposal - Material to order - strordermaterial: "
            + strordermaterial);

        if (!"".equals(strordermaterial)) {
          // Create a new purchase order
          // StringTokenizer + for - insert purchase orders lines with one line per header
          if (strordermaterial.startsWith("("))
            strordermaterial = strordermaterial.substring(1, strordermaterial.length() - 1);
          if (!strordermaterial.equals("")) {
            strordermaterial = Replace.replace(strordermaterial, "'", "");
            StringTokenizer st = new StringTokenizer(strordermaterial, ",", false);
            log4j.debug("Create order from proposal - Material to order - Create purchase order");
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strmProductId = identifier.substring(0, 32);
              // String strmAttributesetinstanceId = identifier.substring(32, 63);
              // String strmLocatorId = identifier.substring(64, 95);
              String strmovementqty = vars.getStringParameter("inpOrderToOrderQty" + identifier,
                  "0");

              log4j
                  .debug("Create order from proposal - Material to order - Create purchase order - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material to order - Create purchase order - movementqty: "
                      + strmovementqty);

              String strcOrderId = SequenceIdData.getUUID();
              myMessage = insertOrderHeader(conn, vars, strcOrderId, strmProductId, "N", null);
              log4j
                  .debug("Create order from proposal - Material to order - Create purchase order - Header inserted");
              if (myMessage != null) {
                if (myMessage.getType() != "Error") {
                  txtOrder.append(myMessage.getMessage());
                } else {
                  myMessage.setMessage(Utility.messageBD(this, "Created", vars.getLanguage()));
                  releaseRollbackConnection(conn);
                }
              }
              int line = 10;
              // Reserve = Y, means that a relationship between purchase orderline and proposal (or
              // sales order) line must be added
              myMessage = insertOrderLine(conn, vars, strcOrderId, line, strmProductId,
                  strmovementqty, null, !"".equals(strreservematerial) ? true : false, strKey);
              log4j
                  .debug("Create order from proposal - Material to order - Create purchase order - Line inserted");
              line = line + 10;
            }
          }
        }

        /*
         * if (!"".equals(strreservematerial)) { // StringTokenizer + for - insert material movement
         * lines with one material movement header // Material movement if
         * (strreservematerial.startsWith("(")) strreservematerial = strreservematerial.substring(1,
         * strreservematerial.length() - 1); if (!strreservematerial.equals("")) {
         * strreservematerial = Replace.replace(strreservematerial, "'", ""); StringTokenizer st =
         * new StringTokenizer(strreservematerial, ",", false); // Movementid, client, org, user,
         * name, description, movementdate, documentno
         * log4j.debug("Create order from proposal - Material to order - Material movement"); String
         * strmMovementId = SequenceIdData.getUUID(); String strDocumentno =
         * Utility.getDocumentNo(this, vars, "", "M_Movement", "", "", false, true);
         * CreateOrderFromProposalData[] dataOrder = CreateOrderFromProposalData.selectOrder(this,
         * strKey); CreateOrderFromProposalData.insertMovement(conn, this, strmMovementId,
         * vars.getClient(), vars.getOrg(), vars.getUser(), dataOrder[0].documentno + " - " +
         * dataOrder[0].dateordered, dataOrder[0].documentno+ " - " + dataOrder[0].dateordered,
         * dataOrder[0].dateordered, strDocumentno); log4j.debug(
         * "Create order from proposal - Material to order - Material movement - Movement header inserted"
         * ); int line = 10; while (st.hasMoreTokens()) { String identifier = st.nextToken().trim();
         * log4j
         * .debug("Create order from proposal - Material to order - Material movement - identifier: "
         * +identifier); String strmProductId = identifier.substring(0, 32);
         * log4j.debug("Create order from proposal - Material to order - Material movement - product: "
         * +strmProductId); String strmAttributesetinstanceId = identifier.substring(32, 64);
         * log4j.debug
         * ("Create order from proposal - Material to order - Material movement - instance: "
         * +strmAttributesetinstanceId); String strmLocatorId = identifier.substring(64, 96);
         * log4j.debug
         * ("Create order from proposal - Material to order - Material movement - locator: "
         * +strmLocatorId); String strmovementqty =
         * vars.getStringParameter("inpReserveMaterialQty"+identifier, "0");
         * 
         * log4j.debug("Create order from proposal - Material to order - Material movement - product: "
         * +strmProductId); log4j.debug(
         * "Create order from proposal - Material to order - Material movement - attribute: "
         * +strmAttributesetinstanceId);
         * log4j.debug("Create order from proposal - Material to order - Material movement - locator: "
         * +strmLocatorId); log4j.debug(
         * "Create order from proposal - Material to order - Material movement - movement qty: "
         * +strmovementqty);
         * 
         * // Movementlineid, client, org, user, movement, locator, locatorto, product, line,
         * movementqty, description, attributesetinstance, productuom, quantityorder, uom String
         * strmMovementLineId = SequenceIdData.getUUID(); String strcUomId =
         * CreateOrderFromProposalData.selectUom(this, strmProductId); String strmLocatortoId =
         * CreateOrderFromProposalData.selectLocatorto(this);
         * log4j.debug("Create order from proposal - Material to order - Material movement - uom: "
         * +strcUomId); log4j.debug(
         * "Create order from proposal - Material to order - Material movement - locator to: "
         * +strmLocatortoId); CreateOrderFromProposalData.insertMovementLine(conn, this,
         * strmMovementLineId, vars.getClient(), vars.getOrg(), vars.getUser(), strmMovementId,
         * strmLocatorId, strmLocatortoId, strmProductId, new Integer(line).toString(),
         * strmovementqty,"", strmAttributesetinstanceId, "", "0", strcUomId);
         * 
         * line = line + 10;
         * 
         * //Assign movement line to order line, to keep the lines related // First, check if a line
         * exist to this orderline } } }
         */

        // Material pending to receive. It must show the order which the material is reserved.:
        // Option 1: the material is reserved, so the check should not appear. The user can order a
        // new one.
        // Option 2: the material is not reserved, so the check appears. The user can reserve or
        // order
        // a new one. Similar to material not reserved.
        //

        strreservematerial = vars.getInStringParameter("inpReservePending", "");
        strordermaterial = vars.getInStringParameter("inpOrderPending", "");

        log4j
            .debug("Create order from proposal - Material pending to recieve - strreservematerial: "
                + strreservematerial);
        log4j.debug("Create order from proposal - Material pending to receive - strordermaterial: "
            + strordermaterial);

        // Option 2: reserve the material
        //

        // Reserve the material means, associate the purchase order line with the sales
        // order/proposal line
        if (!"".equals(strreservematerial)) {
          // StringTokenizer + for - insert material movement lines with one material movement
          // header
          // Material movement
          if (strreservematerial.startsWith("("))
            strreservematerial = strreservematerial.substring(1, strreservematerial.length() - 1);
          if (!strreservematerial.equals("")) {
            strreservematerial = Replace.replace(strreservematerial, "'", "");
            StringTokenizer st = new StringTokenizer(strreservematerial, ",", false);
            // Movementid, client, org, user, name, description, movementdate, documentno
            log4j
                .debug("Create order from proposal - Material pending to receive - Material movement");
            // String strmMovementId = SequenceIdData.getUUID();
            /*
             * String strDocumentno = Utility.getDocumentNo(this, vars, "", "M_Movement", "", "",
             * false, true); log4j .debug(
             * "Create order from proposal - Material pending to receive - Material movement - strKey: "
             * + strKey); CreateOrderFromProposalData[] dataOrder =
             * CreateOrderFromProposalData.selectOrder(this, strKey);
             * CreateOrderFromProposalData.insertMovement(conn, this, strmMovementId,
             * vars.getClient(), vars.getOrg(), vars.getUser(), dataOrder[0].documentno + " - " +
             * dataOrder[0].dateordered, dataOrder[0].documentno + " - " + dataOrder[0].dateordered,
             * dataOrder[0].dateordered, strDocumentno); int line = 10;
             */
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strcOrderlineId = identifier.substring(0, 32);
              String strmProductId = (identifier.length() > 32) ? identifier.substring(32, 64) : "";
              String strmAttributesetinstanceId = (identifier.length() > 64) ? identifier
                  .substring(64, identifier.length()) : "";
              // String strmLocatorId = identifier.substring(64, 96);
              String strmovementqty = vars.getStringParameter("inpReservePendingQty" + identifier,
                  "0");

              log4j
                  .debug("Create order from proposal - Material pending to receive - Material movement - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Material movement - attribute: "
                      + strmAttributesetinstanceId);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Material movement - orderline: "
                      + strcOrderlineId);
              /*
               * log4j .debug(
               * "Create order from proposal - Material pending to receive - Material movement - locator: "
               * + strmLocatorId);
               */
              log4j
                  .debug("Create order from proposal - Material pending to receive - Material movement - movement qty: "
                      + strmovementqty);

              // Movementlineid, client, org, user, movement, locator, locatorto, product, line,
              // movementqty, description, attributesetinstance, productuom, quantityorder, uom
              /*
               * String strmMovementLineId = SequenceIdData.getUUID(); String strcUomId =
               * CreateOrderFromProposalData.selectUom(this, strmProductId); String strmLocatortoId
               * = CreateOrderFromProposalData.selectLocatorto(this); log4j .debug(
               * "Create order from proposal - Material pending to receive - Material movement - uom: "
               * + strcUomId); log4j .debug(
               * "Create order from proposal - Material pending to receive - Material movement - locator to: "
               * + strmLocatortoId);
               * 
               * CreateOrderFromProposalData.insertMovementLine(conn, this, strmMovementLineId,
               * vars.getClient(), vars.getOrg(), vars.getUser(), strmMovementId, strmLocatorId,
               * strmLocatortoId, strmProductId, new Integer(line).toString(), strmovementqty, "",
               * strmAttributesetinstanceId, "", "", strcUomId);
               * 
               * line = line + 10;
               */
              CreateOrderFromProposalData.updateMatch(conn, this, strcOrderlineId, strmProductId,
                  strKey);

              log4j
                  .debug("Create order from proposal - Material pending to receive - Material movement - movement line inserted");

              // Assign movement line to order line, to keep the lines related
              // First, check if a line exist to this orderline
            }
          }
        }

        // Option 1 and 2: the users orders a new one

        if (!"".equals(strordermaterial)) {
          // Create a new purchase order
          // StringTokenizer + for - insert purchase orders lines with one line per header
          if (strordermaterial.startsWith("("))
            strordermaterial = strordermaterial.substring(1, strordermaterial.length() - 1);
          if (!strordermaterial.equals("")) {
            strordermaterial = Replace.replace(strordermaterial, "'", "");
            StringTokenizer st = new StringTokenizer(strordermaterial, ",", false);
            log4j
                .debug("Create order from proposal - Material pending to receive - Create purchase order");
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strcOrderlineId = identifier.substring(0, 32);
              String strmProductId = (identifier.length() > 32) ? identifier.substring(32, 64) : "";
              String strmAttributesetinstanceId = (identifier.length() > 64) ? identifier
                  .substring(32, identifier.length()) : "";
              // String strmAttributesetinstanceId = identifier.substring(32, 63);
              // String strmLocatorId = identifier.substring(64, 95);
              String strmovementqty = vars.getStringParameter("inpOrderPendingQty" + identifier,
                  "0");

              log4j
                  .debug("Create order from proposal - Material pending to receive - Create purchase order - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Create purchase order - movementqty: "
                      + strmovementqty);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Create purchase order - order line: "
                      + strcOrderlineId);

              String strcOrderId = SequenceIdData.getUUID();
              myMessage = insertOrderHeader(conn, vars, strcOrderId, strmProductId, "N", null);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Create purchase order - Header inserted");
              if (myMessage != null) {
                if (myMessage.getType() != "Error") {
                  txtOrder.append(myMessage.getMessage());
                } else {
                  myMessage.setMessage(Utility.messageBD(this, "Created", vars.getLanguage()));
                  releaseRollbackConnection(conn);
                }
              }
              int line = 10;
              myMessage = insertOrderLine(conn, vars, strcOrderId, line, strmProductId,
                  strmovementqty, null, false, strKey);
              log4j
                  .debug("Create order from proposal - Material pending to receive - Create purchase order - Line inserted");
              line = line + 10;
            }
          }
        }

        // Similar products:
        // Option 1: reserve the material
        // Option 2: reserve and order the material

        strreservematerial = vars.getInStringParameter("inpReservedSimilar", "");
        strordermaterial = vars.getInStringParameter("inpOrderSimilar", "");

        log4j.debug("Create order from proposal - Material similar products - strreservematerial: "
            + strreservematerial);
        log4j.debug("Create order from proposal - Material similar products - strordermaterial: "
            + strordermaterial);

        // Option 1 reserve the material

        if (!"".equals(strreservematerial)) {
          // StringTokenizer + for - insert material movement lines with one material movement
          // header
          // Material movement
          if (strreservematerial.startsWith("("))
            strreservematerial = strreservematerial.substring(1, strreservematerial.length() - 1);
          if (!strreservematerial.equals("")) {
            strreservematerial = Replace.replace(strreservematerial, "'", "");
            StringTokenizer st = new StringTokenizer(strreservematerial, ",", false);
            // Movementid, client, org, user, name, description, movementdate, documentno
            log4j
                .debug("Create order from proposal - Material similar products - Material movement");
            String strmMovementId = SequenceIdData.getUUID();
            String strDocumentno = Utility.getDocumentNo(this, vars, "", "M_Movement", "", "",
                false, true);
            log4j
                .debug("Create order from proposal - Material similar products - Material movement - strKey: "
                    + strKey);
            CreateOrderFromProposalData[] dataOrder = CreateOrderFromProposalData.selectOrder(this,
                strKey);
            CreateOrderFromProposalData.insertMovement(conn, this, strmMovementId,
                vars.getClient(), vars.getOrg(), vars.getUser(), dataOrder[0].documentno + " - "
                    + dataOrder[0].dateordered, dataOrder[0].documentno + " - "
                    + dataOrder[0].dateordered, dataOrder[0].dateordered, strDocumentno);
            log4j
                .debug("Create order from proposal - Material similar products - Material movement - Movement header inserted");
            int line = 10;
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strmProductId = identifier.substring(0, 32);
              String strmLocatorId = (identifier.length() > 32) ? identifier.substring(32, 64) : "";
              String strmAttributesetinstanceId = (identifier.length() > 64) ? identifier
                  .substring(64, identifier.length()) : "";
              String strmovementqty = vars.getStringParameter("inpReserveSimilarQty" + identifier,
                  "0");

              log4j
                  .debug("Create order from proposal - Material similar products - Material movement - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material similar products - Material movement - attribute: "
                      + strmAttributesetinstanceId);
              log4j
                  .debug("Create order from proposal - Material similar products - Material movement - locator: "
                      + strmLocatorId);
              log4j
                  .debug("Create order from proposal - Material similar products - Material movement - movement qty: "
                      + strmovementqty);

              // Movementlineid, client, org, user, movement, locator, locatorto, product, line,
              // movementqty, description, attributesetinstance, productuom, quantityorder,uom
              String strmMovementLineId = SequenceIdData.getUUID();
              String strcUomId = CreateOrderFromProposalData.selectUom(this, strmProductId);
              String strmLocatortoId = CreateOrderFromProposalData.selectLocatorto(this);
              CreateOrderFromProposalData.insertMovementLine(conn, this, strmMovementLineId,
                  vars.getClient(), vars.getOrg(), vars.getUser(), strmMovementId, strmLocatorId,
                  strmLocatortoId, strmProductId, new Integer(line).toString(), strmovementqty, "",
                  strmAttributesetinstanceId, "", "", strcUomId);

              line = line + 10;

              log4j
                  .debug("Create order from proposal - Material similar products - Material movement - movement line inserted");

              // Assign movement line to order line, to keep the lines related
              // First, check if a line exist to this orderline
              CreateOrderFromProposalData.updateMatchMovement(conn, this, strmMovementLineId,
                  strmProductId, strKey);
            }
          }
        }

        // Option 1 order the material

        if (!"".equals(strordermaterial)) {
          // Create a new purchase order
          // StringTokenizer + for - insert purchase orders lines with one line per header
          if (strordermaterial.startsWith("("))
            strordermaterial = strordermaterial.substring(1, strordermaterial.length() - 1);
          if (!strordermaterial.equals("")) {
            strordermaterial = Replace.replace(strordermaterial, "'", "");
            StringTokenizer st = new StringTokenizer(strordermaterial, ",", false);
            log4j
                .debug("Create order from proposal - Material similar products - Create purchase order");
            while (st.hasMoreTokens()) {
              String identifier = st.nextToken().trim();
              String strmProductId = identifier.substring(0, 32);
              // String strmAttributesetinstanceId = identifier.substring(32, 63);
              // String strmLocatorId = identifier.substring(64, 95);
              String strmovementqty = vars.getStringParameter("inpOrderSimilarQty" + identifier,
                  "0");
              log4j
                  .debug("Create order from proposal - Material similar products - Create purchase order - product: "
                      + strmProductId);
              log4j
                  .debug("Create order from proposal - Material similar products - Create purchase order - movementqty: "
                      + strmovementqty);

              String strcOrderId = SequenceIdData.getUUID();
              myMessage = insertOrderHeader(conn, vars, strcOrderId, strmProductId, "N", null);
              log4j
                  .debug("Create order from proposal - Material similar products - Create purchase order - Header inserted");
              if (myMessage != null) {
                if (myMessage.getType() != "Error") {
                  txtOrder.append(myMessage.getMessage());
                } else {
                  myMessage.setMessage(Utility.messageBD(this, "Created", vars.getLanguage()));
                  releaseRollbackConnection(conn);
                }
              }
              int line = 10;
              myMessage = insertOrderLine(conn, vars, strcOrderId, line, strmProductId,
                  strmovementqty, null, true, strKey);
              log4j
                  .debug("Create order from proposal - Material similar products - Create purchase order - Line inserted");

              line = line + 10;
            }
          }
        }
      } else {
        // A new order must be created associated to the proposal (which is a order too)
        // The data must be copied from the proposal
        String strcOrderId = SequenceIdData.getUUID();
        log4j.debug("Create order from proposal - creating a new order if needed - strkey: "
            + strKey);
        CreateOrderFromProposalData[] dataOrder = CreateOrderFromProposalData.selectProposal(conn,
            this, strKey);

        log4j
            .debug("Create order from proposal - Create a new order associated to the actual proposal - length: "
                + dataOrder.length);
        if (dataOrder != null && dataOrder.length != 0) {
          myMessage = insertOrderHeader(conn, vars, strcOrderId, "", "Y", dataOrder);
          int line = 10;
          for (int j = 0; j < dataOrder.length; j++) {
            myMessage = insertOrderLine(conn, vars, strcOrderId, line, "", "", dataOrder[j], false,
                strKey);
            line = line + 10;
          }
        }
      }
      releaseCommitConnection(conn);
    } catch (Exception e) {
      try {
        releaseRollbackConnection(conn);
      } catch (Exception ignored) {
      }
      log4j.warn("Rollback in transaction", e);
      myMessage = new OBError();
      myMessage.setType("Error");
      myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
      myMessage.setMessage(Utility.messageBD(this, "ProcessRunError", vars.getLanguage()));
      return myMessage;
    }
    myMessage = new OBError();
    myMessage.setType("Success");
    myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
    // myMessage.setMessage(Utility.messageBD(this, "RecordsCopied", vars.getLanguage()) + " " + i);
    return myMessage;
  }

  private OBError insertOrderHeader(Connection conn, VariablesSecureApp vars, String stcOrderId,
      String strmProductId, String issotrx, CreateOrderFromProposalData[] dataOrder) {
    log4j.debug("Insert purchase order header");
    OBError myMessage = new OBError();

    // Create a Purchase order. The partner must be selected, depending on the vendor associated to
    // the product

    String strDocStatus = "DR";
    String strDocAction = "CO";
    String strProcessing = "N";
    String docType = "0";
    log4j.debug("Create order from proposal - insert order header - issotrx: " + issotrx);

    // if ("".equals(strmPricelistId)) {
    // myMessage.setType("Error");
    // myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
    // myMessage.setMessage(Utility.messageBD(this, "TheCustomer", vars.getLanguage()) + " " +
    // Utility.messageBD(this, "PricelistNotdefined", vars.getLanguage() + "."));
    // return myMessage;
    // } else {
    try {
      if ("N".equals(issotrx)) {
        log4j.debug("Insert order header - purchase product: " + strmProductId);
        String strcBpartnerId = CreateOrderFromProposalData.selectVendor(this, strmProductId);
        log4j.debug("Insert order header - vendor id: " + strcBpartnerId);
        BpartnerMiscData[] data1 = null;
        data1 = BpartnerMiscData.select(this, strcBpartnerId);
        log4j.debug("Insert order header - data vendor: " + data1.length);
        String strBPCCurrencyId = CreateOrderFromProposalData.selectCurrency(this,
            data1[0].poPricelistId);
        log4j.debug("Insert order header - currency id: " + strBPCCurrencyId);
        log4j.debug("Insert order header - pricelist: " + data1[0].poPricelistId);
        log4j.debug("Insert order header - payment method: " + data1[0].poPaymentmethodId);
        if (data1[0].poPaymentmethodId.equals("") || data1[0].poPaymentmethodId == null) {
          myMessage.setType("Error");
          myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
          myMessage.setMessage(Utility.messageBD(this, "TheCustomer", vars.getLanguage()) + ' '
              + Utility.messageBD(this, "PayementMethodNotdefined", vars.getLanguage()) + ".");
          return myMessage;
        } else {
          if (data1[0].paymentrulepo.equals("") || data1[0].paymentrulepo == null) {
            data1[0].paymentrulepo = "P";
          }
          String docTargetType = CreateOrderFromProposalData.cDoctypeTarget(conn, this,
              vars.getClient(), vars.getOrg());
          log4j.debug("Insert order header purchase - doc target type: " + docTargetType);
          String strDocumentNo = Utility.getDocumentNo(this, vars, "", "C_Order", docTargetType,
              docTargetType, false, true);
          log4j.debug("Insert order header purchase - documentno: " + strDocumentNo);
          CreateOrderFromProposalData
              .insertCOrder(
                  conn,
                  this,
                  stcOrderId,
                  vars.getClient(),
                  vars.getOrg(),
                  vars.getUser(),
                  strDocumentNo,
                  strDocStatus,
                  strDocAction,
                  strProcessing,
                  docType,
                  docTargetType,
                  DateTimeData.today(this),
                  DateTimeData.today(this),
                  DateTimeData.today(this),
                  strcBpartnerId,
                  CreateOrderFromProposalData.cBPartnerLocationId(this, strcBpartnerId),
                  CreateOrderFromProposalData.billto(this, strcBpartnerId).equals("") ? CreateOrderFromProposalData
                      .cBPartnerLocationId(this, strcBpartnerId) : CreateOrderFromProposalData
                      .billto(this, strcBpartnerId),
                  strBPCCurrencyId,
                  data1[0].paymentrulepo,
                  data1[0].poPaymentmethodId,
                  data1[0].poPaymenttermId.equals("") ? CreateOrderFromProposalData
                      .selectPaymentTerm(this, vars.getClient()) : data1[0].poPaymenttermId,
                  data1[0].invoicerule.equals("") ? "I" : data1[0].invoicerule,
                  data1[0].deliveryrule.equals("") ? "A" : data1[0].deliveryrule, "I",
                  data1[0].deliveryviarule.equals("") ? "D" : data1[0].deliveryviarule, vars
                      .getWarehouse(), data1[0].poPricelistId, "", "", "", issotrx, "");
          myMessage.setType("Success");
          myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
          myMessage.setMessage(Utility.messageBD(this, "PurchaseOrderDocumentno",
              vars.getLanguage())
              + " "
              + strDocumentNo
              + " "
              + Utility.messageBD(this, "beenCreated", vars.getLanguage()));

        }
      } else {
        String docTargetType = CreateOrderFromProposalData.cDoctypeTarget(conn, this,
            vars.getClient(), vars.getOrg());
        log4j.debug("Create order from proposal - create order header - doctype target: "
            + docTargetType);
        String strDocumentNo = Utility.getDocumentNo(this, vars, "", "C_Order", docTargetType,
            docTargetType, false, true);
        log4j.debug("Create order from proposal - create order header - documentno: "
            + strDocumentNo);
        CreateOrderFromProposalData.insertCOrder(conn, this, stcOrderId, dataOrder[0].adClientId,
            dataOrder[0].adOrgId, vars.getUser(), strDocumentNo, strDocStatus, strDocAction,
            strProcessing, docType, docTargetType, DateTimeData.today(this),
            DateTimeData.today(this), DateTimeData.today(this), dataOrder[0].cBpartnerId,
            dataOrder[0].cBpartnerLocationId, dataOrder[0].billtoId, dataOrder[0].cCurrencyId,
            dataOrder[0].paymentrule, dataOrder[0].finPaymentmethodId, dataOrder[0].cPaymenttermId,
            dataOrder[0].invoicerule, dataOrder[0].deliveryrule, "I", dataOrder[0].deliveryviarule,
            dataOrder[0].mWarehouseId, dataOrder[0].mPricelistId, "", "", "", issotrx, "");
        myMessage.setType("Success");
        myMessage.setTitle(Utility.messageBD(this, "Success", vars.getLanguage()));
        myMessage.setMessage(Utility.messageBD(this, "SalesOrderDocumentno", vars.getLanguage())
            + " " + strDocumentNo + " "
            + Utility.messageBD(this, "beenCreated", vars.getLanguage()));
      }
    } catch (Exception ex) {
      ex.printStackTrace();
      log4j.error(ex);
      myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
      throw new Exception(ex);
      // return myMessage;
    } finally {
      return myMessage;
    }
    // }
  }

  private OBError insertOrderLine(Connection conn, VariablesSecureApp vars, String strCOrderId,
      Integer line, String strmProductId, String strmovementqty, CreateOrderFromProposalData data,
      boolean reserve, String strKey) throws IOException, SQLException {
    OBError myMessage = null;
    myMessage = new OBError();

    String priceactual = "";
    String pricelist = "";
    String pricelimit = "";
    String strCOrderlineID = "";

    // Catch database error message
    try {
      if (data == null) {
        // Determines the date of the expense (strDateExpense)
        // String strDateexpense = data.dateexpense.equals("") ? data.datereport : data.dateexpense;
        // strDateexpense = strDateexpense.equals("") ? DateTimeData.today(this) : strDateexpense;

        // Gets the tax for the sales order line
        String strcBpartnerId = CreateOrderFromProposalData.selectVendor(this, strmProductId);
        log4j.debug("Create order from proposal - insert line - vendor: " + strcBpartnerId);
        String strCTaxID = Tax.get(this, strmProductId, DateTimeData.today(this), vars.getOrg(),
            vars.getWarehouse(),
            CreateOrderFromProposalData.cBPartnerLocationId(this, strcBpartnerId),
            CreateOrderFromProposalData.cBPartnerLocationId(this, strcBpartnerId), "", true);
        log4j.debug("Create order from proposal - insert line - tax: " + strCTaxID);
        if (strCTaxID.equals("") || strCTaxID == null) {
          myMessage.setType("Error");
          myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
          myMessage.setMessage(Utility.messageBD(this, "line", vars.getLanguage()) + " "
              + Utility.messageBD(this, "TaxNotFound", vars.getLanguage()) + ".");
          return myMessage;
        } else {
          // Currency of the expense line
          // String strCCurrencyId = data.cCurrencyId;
          String strmPricelistId = CreateOrderFromProposalData.selectPricelist(conn, this,
              strCOrderId);
          log4j.debug("Create order from proposal - insert line - pricelist from order: "
              + strmPricelistId);
          String strBPCCurrencyId = CreateOrderFromProposalData.selectCurrency(this,
              strmPricelistId);
          log4j.debug("Create order from proposal - insert line - currency from pricelist: "
              + strBPCCurrencyId);
          // Currency of the business partner price list

          String strPrecision = "0";
          String strPricePrecision = "0";
          String strDiscount = "";

          BigDecimal priceActual, priceList, priceLimit, discount;

          // Looks for the prices in the pricelist of the business partner
          CreateOrderFromProposalData[] data3 = CreateOrderFromProposalData.selectPrice(this,
              strmProductId, strmPricelistId, strBPCCurrencyId);
          for (int j = 0; data3 != null && j < data3.length; j++) {
            if (data3[j].validfrom == null
                || data3[j].validfrom.equals("")
                || !DateTimeData.compare(this, DateTimeData.today(this), data3[j].validfrom)
                    .equals("-1")) {
              priceactual = data3[j].pricestd;
              pricelist = data3[j].pricelist;
              pricelimit = data3[j].pricelimit;
            }
          }

          log4j.debug("Create order from proposal - insert line - priceactual: " + priceactual);
          log4j.debug("Create order from proposal - insert line - pricelist: " + pricelist);
          log4j.debug("Create order from proposal - insert line - pricelimit: " + pricelimit);

          // If the currency of the expense line is not the same as
          // the currency of the business partner pricelist, make the
          // corresponding conversions
          // if (!strCCurrencyId.equals(strBPCCurrencyId)) {
          // Converts priceactual, pricelist and pricelimit to the
          // currency of the business partner pricelist
          // priceactual = ExpenseSOrderData.selectConvertedAmt(this, priceactual, strCCurrencyId,
          // strBPCCurrencyId, strDateexpense, vars.getClient(), vars.getOrg());
          // pricelist = ExpenseSOrderData.selectConvertedAmt(this, pricelist, strCCurrencyId,
          // strBPCCurrencyId, strDateexpense, vars.getClient(), vars.getOrg());
          // pricelimit = ExpenseSOrderData.selectConvertedAmt(this, pricelimit, strCCurrencyId,
          // strBPCCurrencyId, strDateexpense, vars.getClient(), vars.getOrg());
          // }

          // If priceactual is null
          if (priceactual.equals("") || priceactual == null) {
            myMessage.setType("Error");
            myMessage.setTitle(Utility.messageBD(this, "Error", vars.getLanguage()));
            myMessage.setMessage(Utility.messageBD(this, "line", vars.getLanguage()) + " "
                + Utility.messageBD(this, "PriceNotFound", vars.getLanguage()) + ".");
            return myMessage;
          } else {
            // Recalculates precisions for the business partner pricelist
            // currency
            CreateOrderFromProposalData[] data4 = CreateOrderFromProposalData.selectPrecisions(
                this, strBPCCurrencyId);
            if (data4 != null && data4.length > 0) {
              strPrecision = data4[0].stdprecision.equals("") ? "0" : data4[0].stdprecision;
              strPricePrecision = data4[0].priceprecision.equals("") ? "0"
                  : data4[0].priceprecision;
            }
            int StdPrecision = Integer.valueOf(strPrecision).intValue();
            int PricePrecision = Integer.valueOf(strPricePrecision).intValue();
            priceActual = (priceactual.equals("") ? ZERO : (new BigDecimal(priceactual)));
            priceActual = priceActual.setScale(PricePrecision, BigDecimal.ROUND_HALF_UP);
            priceList = (pricelist.equals("") ? ZERO : (new BigDecimal(pricelist)));
            priceList = priceList.setScale(PricePrecision, BigDecimal.ROUND_HALF_UP);
            priceLimit = (pricelimit.equals("") ? ZERO : (new BigDecimal(pricelimit)));
            priceLimit = priceLimit.setScale(PricePrecision, BigDecimal.ROUND_HALF_UP);

            log4j.debug("Create order from proposal - insert line - priceactual after precision: "
                + priceactual);
            log4j.debug("Create order from proposal - insert line - pricelist after precision: "
                + pricelist);
            log4j.debug("Create order from proposal - insert line - pricelimit after precision: "
                + pricelimit);

            // Calculating discount
            if (priceList.compareTo(BigDecimal.ZERO) == 0)
              discount = ZERO;
            else {
              if (log4j.isDebugEnabled())
                log4j.debug("pricelist:" + Double.toString(priceList.doubleValue()));
              if (log4j.isDebugEnabled())
                log4j.debug("priceActual:" + Double.toString(priceActual.doubleValue()));
              discount = ((priceList.subtract(priceActual)).divide(priceList, 12,
                  BigDecimal.ROUND_HALF_EVEN)).multiply(new BigDecimal("100"));
            }
            if (log4j.isDebugEnabled())
              log4j.debug("Discount: " + discount.toString());
            if (discount.scale() > StdPrecision) {
              discount = discount.setScale(StdPrecision, BigDecimal.ROUND_HALF_UP);
            }
            if (log4j.isDebugEnabled())
              log4j.debug("Discount rounded: " + discount.toString());

            priceactual = priceActual.toString();
            pricelist = priceList.toString();
            pricelimit = priceLimit.toString();
            strDiscount = discount.toString();

            strCOrderlineID = SequenceIdData.getUUID();

            CreateOrderFromProposalData.insertCOrderline(conn, this, strCOrderlineID,
                vars.getClient(), vars.getOrg(), vars.getUser(), strCOrderId,
                Integer.toString(line), strcBpartnerId,
                CreateOrderFromProposalData.cBPartnerLocationId(this, strcBpartnerId),
                DateTimeData.today(this), DateTimeData.today(this), "", strmProductId,
                vars.getWarehouse(), CreateOrderFromProposalData.selectUom(this, strmProductId),
                strmovementqty, strBPCCurrencyId, pricelist, priceactual, strmPricelistId,
                pricelimit, strCTaxID, "", strDiscount);

          }
        }
      } else {
        strCOrderlineID = SequenceIdData.getUUID();
        log4j.error("Create order from proposal order line when data is not null");
        CreateOrderFromProposalData.insertCOrderline(conn, this, strCOrderlineID, data.adClientId,
            data.adOrgId, vars.getUser(), strCOrderId, Integer.toString(line), data.cBpartnerId,
            data.cBpartnerLocationId, DateTimeData.today(this), DateTimeData.today(this), "",
            data.mProductId, data.mWarehouseId, data.cUomId, data.qtyordered, data.cCurrencyId,
            data.pricelist, data.priceactual, data.mPricelistId, data.pricelimit, data.cTaxId, "",
            data.discount);

      }
      if (reserve)
        CreateOrderFromProposalData.updateMatch(conn, this, strCOrderlineID, strmProductId, strKey);
    } catch (ServletException ex) {
      myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
      return myMessage;
    }
    return myMessage;
  }

  private void printPage(HttpServletResponse response, VariablesSecureApp vars, String strKey,
      String windowId, String strTab, String strProcessId) throws IOException, ServletException {
    if (log4j.isDebugEnabled())
      log4j.debug("Output: Button create order from proposal");

    ActionButtonDefaultData[] data = null;
    String strHelp = "", strDescription = "";
    if (vars.getLanguage().equals("en_US"))
      data = ActionButtonDefaultData.select(this, strProcessId);
    else
      data = ActionButtonDefaultData.selectLanguage(this, vars.getLanguage(), strProcessId);

    if (data != null && data.length != 0) {
      strDescription = data[0].description;
      strHelp = data[0].help;
    }
    /*
     * String[] discard = { "" }; if (strHelp.equals("")) discard[0] = new String("helpDiscard");
     * XmlDocument xmlDocument = xmlEngine.readXmlTemplate(
     * "org/openbravo/furniture/ad_actionbutton/CreateOrderFromProposal",
     * discard).createXmlDocument(); xmlDocument.setParameter("key", strKey);
     * xmlDocument.setParameter("window", windowId); xmlDocument.setParameter("tab", strTab);
     * xmlDocument.setParameter("language", "defaultLang=\"" + vars.getLanguage() + "\";");
     * xmlDocument.setParameter("question", Utility.messageBD(this, "StartProcess?",
     * vars.getLanguage())); xmlDocument.setParameter("directory", "var baseDirectory = \"" +
     * strReplaceWith + "/\";\n"); xmlDocument.setParameter("theme", vars.getTheme());
     * xmlDocument.setParameter("description", strDescription); xmlDocument.setParameter("help",
     * strHelp);
     */

    String[] discard = { "" };
    XmlDocument xmlDocument = xmlEngine.readXmlTemplate(
        "org/openbravo/furniture/ad_actionbutton/CreateOrderFromProposal", discard)
        .createXmlDocument();
    ToolBar toolbar = new ToolBar(this, vars.getLanguage(), "CreateOrderFromProposal", false, "",
        "", "", false, "ad_actionbutton", strReplaceWith, false, true);
    toolbar.prepareSimpleToolBarTemplate();
    xmlDocument.setParameter("toolbar", toolbar.toString());

    OBError myMessage = null;
    try {
      WindowTabs tabs = new WindowTabs(this, vars,
          "org.openbravo.furniture.ad_actionbutton.CreateOrderFromProposal");
      log4j.debug("Create order from proposal - window tabs");
      xmlDocument.setParameter("parentTabContainer", tabs.parentTabs());
      log4j.debug("Create order from proposal - window tabs - parent tabs");
      xmlDocument.setParameter("mainTabContainer", tabs.mainTabs());
      log4j.debug("Create order from proposal - window tabs - main tab");
      xmlDocument.setParameter("childTabContainer", tabs.childTabs());
      log4j.debug("Create order from proposal - window tabs - child tab");
      xmlDocument.setParameter("theme", vars.getTheme());
      NavigationBar nav = new NavigationBar(this, vars.getLanguage(),
          "CreateOrderFromProposal.html", classInfo.id, classInfo.type, strReplaceWith,
          tabs.breadcrumb());
      xmlDocument.setParameter("navigationBar", nav.toString());
      log4j.debug("Create order from proposal - window tabs - navigation bar");
      LeftTabsBar lBar = new LeftTabsBar(this, vars.getLanguage(), "CreateOrderFromProposal.html",
          strReplaceWith);
      log4j.debug("Create order from proposal - window tabs - left tabs");
      xmlDocument.setParameter("leftTabs", lBar.manualTemplate());
    } catch (Exception ex) {
      throw new ServletException(ex);
    }
    {
      myMessage = vars.getMessage("CreateOrderFromProposal");
      vars.removeMessage("CreateOrderFromProposal");
      if (myMessage != null) {
        xmlDocument.setParameter("messageType", myMessage.getType());
        xmlDocument.setParameter("messageTitle", myMessage.getTitle());
        xmlDocument.setParameter("messageMessage", myMessage.getMessage());
      }
    }
    log4j.debug("Create order from proposal - before xml document");
    xmlDocument.setParameter("calendar", vars.getLanguage().substring(0, 2));
    xmlDocument.setParameter("directory", "var baseDirectory = \"" + strReplaceWith + "/\";\n");
    xmlDocument.setParameter("paramLanguage", "defaultLang=\"" + vars.getLanguage() + "\";");

    xmlDocument.setParameter("window", windowId);
    xmlDocument.setParameter("tab", strTab);
    xmlDocument.setParameter("process", strProcessId);
    /*
     * try { ComboTableData comboTableData = new ComboTableData(vars, this, "TABLEDIR", "AD_Org_ID",
     * "", "AD_Org Security validation", Utility.getContext(this, vars, "#User_Org",
     * "MaterialReceiptPending"), Utility.getContext(this, vars, "#User_Client",
     * "MaterialReceiptPending"), 0); Utility.fillSQLParameters(this, vars, null, comboTableData,
     * "MaterialReceiptPending", ""); xmlDocument.setData("reportAD_Org_ID", "liststructure",
     * comboTableData.select(false)); comboTableData = null; } catch (Exception ex) { throw new
     * ServletException(ex); }
     */

    // xmlDocument.setParameter("paramMessage",
    // (strMessage.equals("")?"":"alert('" + strMessage + "');"));
    xmlDocument.setParameter("dateFromdisplayFormat", vars.getSessionValue("#AD_SqlDateFormat"));
    xmlDocument.setParameter("dateFromsaveFormat", vars.getSessionValue("#AD_SqlDateFormat"));
    xmlDocument.setParameter("displayFormat", vars.getSessionValue("#AD_SqlDateFormat"));

    // Partner section:
    // If the partner in the order or proposal is anonymous, the text boxes appears empty
    // If the partner is not the anonymous one, the text boxes appears selected

    log4j.debug("Create order from proposal - window tabs - str key: " + strKey);
    String anonymous = CreateOrderFromProposalData.isanonimous(this, strKey);
    log4j.debug("Create order from proposal - window tabs - anonymous: " + anonymous);
    CreateOrderFromProposalData[] dataPartner = null;
    if ("Y".equals(anonymous))
      CreateOrderFromProposalData.set();
    else
      dataPartner = CreateOrderFromProposalData.selectPartner(this, strKey);

    if (dataPartner == null || dataPartner.length == 0)
      dataPartner = CreateOrderFromProposalData.set();

    // Warehouse not reserved section
    // Show data stored in not reserved warehouse
    log4j.debug("Create order from proposal - edit - before not reserved");
    CreateOrderFromProposalData[] dataWarehouseNotReserved = CreateOrderFromProposalData
        .selectWarehouseNotReserved(this, strKey,
            Utility.getContext(this, vars, "#User_Client", "CreateOrderFromProposal"),
            Utility.getContext(this, vars, "#AccessibleOrgTree", "CreateOrderFromProposal"),
            DateTimeData.nDaysAfter(this, DateTimeData.today(this), "1"));

    if (dataWarehouseNotReserved == null || dataWarehouseNotReserved.length == 0)
      dataWarehouseNotReserved = CreateOrderFromProposalData.set();

    // Material to order section
    // Show data needed to be ordered

    log4j.debug("Create order from proposal - edit - before to order");
    CreateOrderFromProposalData[] dataToOrder = CreateOrderFromProposalData.selectToOrder(this,
        strKey, Utility.getContext(this, vars, "#User_Client", "CreateOrderFromProposal"),
        Utility.getContext(this, vars, "#AccessibleOrgTree", "CreateOrderFromProposal"),
        DateTimeData.nDaysAfter(this, DateTimeData.today(this), "1"));

    if (dataToOrder == null || dataToOrder.length == 0)
      dataToOrder = CreateOrderFromProposalData.set();

    // Material pending to receive
    // Show data pending to receive

    log4j.debug("Create order from proposal - edit - before pending");
    CreateOrderFromProposalData[] dataPending = CreateOrderFromProposalData.selectPending(this,
        Utility.getContext(this, vars, "#User_Client", "CreateOrderFromProposal"),
        Utility.getContext(this, vars, "#AccessibleOrgTree", "CreateOrderFromProposal"), strKey);

    if (dataPending == null || dataPending.length == 0)
      dataPending = CreateOrderFromProposalData.set();

    // Similar material
    // Same product with different attribute in warehouse

    log4j.debug("Create order from proposal - edit - before similar");
    CreateOrderFromProposalData[] dataSimilar = CreateOrderFromProposalData.selectSimilar(this,
        Utility.getContext(this, vars, "#User_Client", "CreateOrderFromProposal"),
        Utility.getContext(this, vars, "#AccessibleOrgTree", "CreateOrderFromProposal"),
        DateTimeData.nDaysAfter(this, DateTimeData.today(this), "1"), strKey);

    if (dataSimilar == null || dataSimilar.length == 0)
      dataSimilar = CreateOrderFromProposalData.set();

    // Trasport

    try {
      ComboTableData comboTableData = new ComboTableData(vars, this, "TABLEDIR",
          "Pec_Transport_ID", "", "", Utility.getContext(this, vars, "#User_Org",
              "CreateOrderFromProposal"), Utility.getContext(this, vars, "#User_Client",
              "CreateOrderFromProposal"), 0);
      Utility.fillSQLParameters(this, vars, null, comboTableData, "CreateOrderFromProposal", "");
      xmlDocument.setData("reportPec_Transport_ID", "liststructure", comboTableData.select(false));
      comboTableData = null;
    } catch (Exception ex) {
      throw new ServletException(ex);
    }

    try {
      ComboTableData comboTableData = new ComboTableData(vars, this, "TABLEDIR", "C_Region_ID", "",
          "", Utility.getContext(this, vars, "#User_Org", "CreateOrderFromProposal"),
          Utility.getContext(this, vars, "#User_Client", "CreateOrderFromProposal"), 0);
      Utility.fillSQLParameters(this, vars, null, comboTableData, "CreateOrderFromProposal", "");
      xmlDocument.setData("reportC_Region_ID", "liststructure", comboTableData.select(false));
      comboTableData = null;
    } catch (Exception ex) {
      throw new ServletException(ex);
    }

    try {
      ComboTableData comboTableData = new ComboTableData(vars, this, "TABLEDIR",
          "FIN_Paymentmethod_ID", "", "", Utility.getContext(this, vars, "#User_Org",
              "CreateOrderFromProposal"), Utility.getContext(this, vars, "#User_Client",
              "CreateOrderFromProposal"), 0);
      Utility.fillSQLParameters(this, vars, null, comboTableData, "CreateOrderFromProposal", "");
      xmlDocument.setData("reportFin_Paymentmethod_ID", "liststructure",
          comboTableData.select(false));
      comboTableData = null;
    } catch (Exception ex) {
      throw new ServletException(ex);
    }

    // Show data related to order/proposal
    // Show order/proposal header
    // Show lines with the relationship between order/proposal line and the
    // warehousemovement/purchase order created

    log4j.debug("Create order from proposal - edit - data header");
    CreateOrderFromProposalData[] dataHeader = CreateOrderFromProposalData.selectHeader(this,
        strKey);
    CreateOrderFromProposalData[][] dataLines = null;// new
                                                     // CreateOrderFromProposalData[dataHeader.length][];
    CreateOrderFromProposalData[][] dataLinesMovement = null;
    if (dataHeader == null || dataHeader.length == 0) {
      dataHeader = CreateOrderFromProposalData.set();
      dataLines = new CreateOrderFromProposalData[1][];
      dataLinesMovement = new CreateOrderFromProposalData[1][];
      dataLines[0] = CreateOrderFromProposalData.set();
      dataLinesMovement[0] = CreateOrderFromProposalData.set();
    } else {

      log4j.debug("Create order from proposal - information about order/proposal - data length: "
          + dataHeader.length);

      dataLines = new CreateOrderFromProposalData[dataHeader.length][];
      for (int i = 0; i < dataHeader.length; i++) {
        dataLines[i] = CreateOrderFromProposalData.selectLines(this, dataHeader[i].cOrderlineId);
        if (dataLines[i] == null || dataLines[i].length == 0) {
          dataLines[i] = CreateOrderFromProposalData.set();
        }
      }
      log4j
          .debug("Create order from proposal - information about order/proposal - after data lines");
      dataLinesMovement = new CreateOrderFromProposalData[dataHeader.length][];
      for (int i = 0; i < dataHeader.length; i++) {
        dataLinesMovement[i] = CreateOrderFromProposalData.selectLinesMovement(this,
            dataHeader[i].cOrderlineId);
        if (dataLinesMovement[i] == null || dataLinesMovement[i].length == 0) {
          dataLinesMovement[i] = CreateOrderFromProposalData.set();
        }
      }
      log4j
          .debug("Create order from proposal - information about order/proposal - after data movement");
    }

    xmlDocument.setData("structureHeader", dataHeader);
    xmlDocument.setDataArray("reportLines", "structureLines", dataLines);
    xmlDocument.setDataArray("reportLines", "structureLinesMovement", dataLinesMovement);

    xmlDocument.setData("structurePartner", dataPartner);
    xmlDocument.setData("structureNotReserved", dataWarehouseNotReserved);
    xmlDocument.setData("structureToOrder", dataToOrder);
    xmlDocument.setData("structurePending", dataPending);
    xmlDocument.setData("structureSimilar", dataSimilar);

    xmlDocument.setParameter("cOrderId", strKey);
    xmlDocument.setParameter("paramcRegionId", dataPartner[0].cRegionId);
    xmlDocument.setParameter("paramfinPaymentmethodId", dataPartner[0].finPaymentmethodId);
    response.setContentType("text/html; charset=UTF-8");
    PrintWriter out = response.getWriter();
    xmlDocument.setData("structure1", data);
    out.println(xmlDocument.print());
    out.close();
  }

  public String getServletInfo() {
    return "Servlet Copy from invoice";
  } // end of getServletInfo() method

  private void recalculatePrices(Order objOrder, OrderLine ordLine, Order objCloneOrder,
      OrderLine objCloneOrdLine, TaxRate lineTax) {

    String strPriceVersionId = getPriceListVersion(objOrder.getPriceList().getId(), objOrder
        .getClient().getId(), objCloneOrder.getOrderDate());
    BigDecimal bdPriceList = getPriceList(ordLine.getProduct().getId(), strPriceVersionId);
    BigDecimal bdPriceStd = getPriceStd(ordLine.getProduct().getId(), strPriceVersionId);

    if (!"".equals(bdPriceList) && bdPriceList != null
        && !bdPriceList.equals(BigDecimal.ZERO.setScale(bdPriceList.scale()))) {
      // List Price
      if (objOrder.getPriceList().isPriceIncludesTax()) {
        // If is Price Including Taxes, change gross and then Net
        objCloneOrdLine.setGrossListPrice(bdPriceList);
        objCloneOrdLine.setListPrice(getNetFromGross(bdPriceList, lineTax, objCloneOrder
            .getCurrency().getPricePrecision(), objCloneOrdLine.getOrderedQuantity()));
      } else {
        // If is not Price Including Taxes, change only net
        objCloneOrdLine.setListPrice(bdPriceList);
      }
    }

    if (!"".equals(bdPriceStd) && bdPriceStd != null
        && !bdPriceStd.equals(BigDecimal.ZERO.setScale(bdPriceStd.scale()))) {
      // Unit Price
      if (objOrder.getPriceList().isPriceIncludesTax()) {
        // If is Price Including Taxes, change gross and then Net
        objCloneOrdLine.setGrossUnitPrice(bdPriceStd);
        objCloneOrdLine.setUnitPrice(getNetFromGross(bdPriceStd, lineTax, objCloneOrder
            .getCurrency().getPricePrecision(), BigDecimal.ONE));
      } else {
        // If is not Price Including Taxes, change only net
        objCloneOrdLine.setUnitPrice(bdPriceStd);
      }
    }

    // Discount
    if (bdPriceList == null) {
      bdPriceList = BigDecimal.ZERO;
    }
    if (bdPriceStd == null) {
      bdPriceStd = BigDecimal.ZERO;
    }
    BigDecimal discount = BigDecimal.ZERO;
    discount = bdPriceList
        .subtract(bdPriceStd)
        .multiply(new BigDecimal("100"))
        .divide(bdPriceList, objCloneOrder.getCurrency().getStandardPrecision().intValue(),
            BigDecimal.ROUND_HALF_EVEN);
    objCloneOrdLine.setDiscount(discount);
    // Line Price
    if (objOrder.getPriceList().isPriceIncludesTax()) {
      // If is Price Including Taxes, change gross
      objCloneOrdLine.setLineGrossAmount(objCloneOrdLine.getGrossUnitPrice().multiply(
          objCloneOrdLine.getOrderedQuantity()));
    }
    objCloneOrdLine.setLineNetAmount(objCloneOrdLine.getUnitPrice().multiply(
        objCloneOrdLine.getOrderedQuantity()));
  }

  private void callCOrderPost(Order objCloneOrder) {
    try {
      final List<Object> parameters = new ArrayList<Object>();
      parameters.add(null);
      parameters.add(objCloneOrder.getId());
      final String procedureName = "c_order_post1";
      CallStoredProcedure.getInstance().call(procedureName, parameters, null, true, false);
    } catch (Exception e) {
      throw new OBException(e);
    }
  }

  /**
   * Get the Current version of a price list
   */
  private String getPriceListVersion(String priceList, String clientId, Date orderDate) {
    try {
      String whereClause = " as plv left outer join plv.priceList pl where pl.active='Y' and plv.active='Y' and "
          + " pl.id = :priceList and plv.client.id = :clientId and plv.validFromDate<= :orderDate  order by plv.validFromDate desc";

      OBQuery<PriceListVersion> ppriceListVersion = OBDal.getInstance().createQuery(
          PriceListVersion.class, whereClause);
      ppriceListVersion.setNamedParameter("priceList", priceList);
      ppriceListVersion.setNamedParameter("clientId", clientId);
      ppriceListVersion.setNamedParameter("orderDate", orderDate);
      ppriceListVersion.setMaxResult(1);

      if (!ppriceListVersion.list().isEmpty()) {
        return ppriceListVersion.list().get(0).getId();
      } else {
        return "0";
      }
    } catch (Exception e) {
      throw new OBException(e);
    }
  }

  /**
   * Call Database Procedure to get the List Price of a Product
   */
  private BigDecimal getPriceList(String strProductID, String strPriceVersionId) {
    BigDecimal bdPriceList = null;
    try {
      final List<Object> parameters = new ArrayList<Object>();
      parameters.add(strProductID);
      parameters.add(strPriceVersionId);
      final String procedureName = "M_BOM_PriceList";
      bdPriceList = (BigDecimal) CallStoredProcedure.getInstance().call(procedureName, parameters,
          null);
    } catch (Exception e) {
      throw new OBException(e);
    }

    return bdPriceList;
  }

  /**
   * Call Database Procedure to get the Standard Price of a Product
   */
  private BigDecimal getPriceStd(String strProductID, String strPriceVersionId) {
    BigDecimal bdPriceList = null;
    try {
      final List<Object> parameters = new ArrayList<Object>();
      parameters.add(strProductID);
      parameters.add(strPriceVersionId);
      final String procedureName = "M_BOM_PriceStd";
      bdPriceList = (BigDecimal) CallStoredProcedure.getInstance().call(procedureName, parameters,
          null);
    } catch (Exception e) {
      throw new OBException(e);
    }

    return bdPriceList;
  }

  private FIN_PaymentSchedule generatePaymentPlan(Order order) {
    FIN_PaymentSchedule ps = OBProvider.getInstance().get(FIN_PaymentSchedule.class);
    ps.setClient(order.getClient());
    ps.setOrganization(order.getOrganization());
    ps.setCreatedBy(order.getCreatedBy());
    ps.setCreationDate(new Date());
    ps.setUpdatedBy(order.getUpdatedBy());
    ps.setUpdated(new Date());
    ps.setInvoice(null);
    ps.setOrder(order);
    ps.setCurrency(order.getCurrency());
    ps.setFinPaymentmethod(order.getPaymentMethod());
    ps.setAmount(order.getGrandTotalAmount());
    ps.setDueDate(order.getOrderDate());
    ps.setExpectedDate(order.getOrderDate());
    ps.setOutstandingAmount(order.getGrandTotalAmount());
    ps.setFINPaymentPriority(order.getFINPaymentPriority());
    return ps;
  }

  /**
   * Create a new Payment Schedule Detail for a Payment Plan line
   */
  private FIN_PaymentScheduleDetail generatePaymentPlanDetails(Order order, FIN_PaymentSchedule ps) {
    FIN_PaymentScheduleDetail psd = OBProvider.getInstance().get(FIN_PaymentScheduleDetail.class);
    psd.setClient(order.getClient());
    psd.setOrganization(order.getOrganization());
    psd.setCreatedBy(order.getCreatedBy());
    psd.setCreationDate(new Date());
    psd.setUpdatedBy(order.getUpdatedBy());
    psd.setUpdated(new Date());
    psd.setOrderPaymentSchedule(ps);
    psd.setInvoicePaymentSchedule(null);
    psd.setPaymentDetails(null);
    psd.setAmount(ps.getAmount());
    return psd;
  }

  private OrderLine generateOrderLineDiscount(Entry e, OrderDiscount objCloneDiscount,
      Order objOrder, Order objCloneOrder, int lineNo, BigDecimal cumulativeDiscount,
      BigDecimal discountAmount) {

    BigDecimal amount = (BigDecimal) e.getValue();
    BigDecimal discountedAmount = amount.multiply(discountAmount).divide(new BigDecimal(100));

    OrderLine olDiscount = OBProvider.getInstance().get(OrderLine.class);
    olDiscount.setOrderDiscount(objCloneDiscount);
    olDiscount.setTax(OBDal.getInstance().get(TaxRate.class, e.getKey()));

    if (objOrder.getPriceList().isPriceIncludesTax()) {
      olDiscount.setGrossUnitPrice(discountedAmount.negate());
      olDiscount.setLineGrossAmount(discountedAmount.negate());
      olDiscount.setGrossListPrice(discountedAmount.negate());
      BigDecimal net = getNetFromGross(discountedAmount,
          OBDal.getInstance().get(TaxRate.class, e.getKey()), objCloneOrder.getCurrency()
              .getPricePrecision(), BigDecimal.ONE);
      olDiscount.setUnitPrice(net.negate());
      olDiscount.setLineNetAmount(net.negate());
      olDiscount.setListPrice(net.negate());
    } else {
      olDiscount.setUnitPrice(discountedAmount.negate());
      olDiscount.setLineNetAmount(discountedAmount.negate());
      olDiscount.setListPrice(discountedAmount.negate());
    }

    olDiscount.setSalesOrder(objCloneOrder);
    olDiscount.setReservedQuantity(BigDecimal.ZERO);
    olDiscount.setDeliveredQuantity(BigDecimal.ZERO);
    olDiscount.setInvoicedQuantity(BigDecimal.ZERO);
    olDiscount.setOrganization(objCloneDiscount.getOrganization());
    olDiscount.setLineNo((long) lineNo);
    olDiscount.setOrderDate(new Date());
    olDiscount.setWarehouse(objCloneOrder.getWarehouse());
    olDiscount.setUOM(objCloneDiscount.getDiscount().getProduct().getUOM());
    olDiscount.setCurrency(objCloneOrder.getCurrency());
    // olDiscount.setProduct(objCloneDiscount.getDiscount().getProduct());
    olDiscount.setDescription(objCloneDiscount.getDiscount().getProduct().getName());
    return olDiscount;
  }

  private BigDecimal getNetFromGross(BigDecimal amount, TaxRate tax, Long pricePrecision,
      BigDecimal quantity) {
    BigDecimal netPrice = null;
    try {
      final List<Object> parameters = new ArrayList<Object>();
      parameters.add(tax.getId());
      parameters.add(amount);
      parameters.add(amount);
      parameters.add(pricePrecision);
      parameters.add(quantity);
      final String procedureName = "c_get_net_price_from_gross";
      netPrice = (BigDecimal) CallStoredProcedure.getInstance().call(procedureName, parameters,
          null);
    } catch (Exception e) {
      throw new OBException(e);
    }
    return netPrice;
  }

  private void checkID(final String id) throws ServletException {
    if (!IsIDFilter.instance.accept(id)) {
      log4j.error("Input: " + id + " not accepted by filter: IsIDFilter");
      throw new ServletException("Input: " + id + " is not an accepted input");
    }
  }

}
